﻿using System.Collections.Generic;
using System.IO;
using System.Text;

namespace FemtoHttpd
{
    public abstract class FemtoHttpResponse
    {
        public Encoding ContentEncoding { get; set; } = Encoding.UTF8;
        public string ContentType { get; set; } = "text/plain";
        public FemtoHttpStatus Status { get; set; } = FemtoHttpStatus.Ok;
        /// <summary>
        /// 具有最高优先级
        /// </summary>
        public Dictionary<string, string> Header { get; private set; } = new Dictionary<string, string>();

        protected Stream Output { get; private set; }

        public FemtoHttpResponse(Stream stream)
        {
            this.Output = stream;
        }
        /// <summary>
        /// 检查Header中ContentEncoding，ContentType，Connection 报头，若无则添加相应报头
        /// 你可以重写此方法，必要的时候调用base.CheckHeader(Dictionary<string, string> header);
        /// </summary>
        public virtual void  CheckHeader(Dictionary<string, string> header)
        {
            if (!header.ContainsKey("Content-Type"))
            {
                header["Content-Type"] =  $"{ContentType}; charset={ContentEncoding.BodyName}";
            }else if (!header.ContainsKey("Connection"))
            {
                header["Connection"] = header["Connection"] ?? "close";
            }
        }
        private void WriteHeader()
        {
            CheckHeader(Header);
            StringBuilder builder = new StringBuilder();
            builder.AppendLine($"HTTP/1.1 {Status.Code} {Status.Name}");
            foreach (var h in Header)
            {
                builder.AppendLine(h.Key + ": " + h.Value);
            }
            builder.AppendLine();
            byte[] headerArray = Encoding.ASCII.GetBytes(builder.ToString());
            Output.Write(headerArray, 0, headerArray.Length);
        }
        protected abstract void WriteContent();
        /// <summary>
        /// Call at last
        /// </summary>
        public void ProcessResponse()
        {
            WriteHeader();
            WriteContent();
            Output.Flush();
        }
    }
}
